import json
import datetime
import random
from random import sample
from typing import Any
from django.shortcuts import render
from django.views import View
from django.http.response import JsonResponse

# from django.core.cache import cache
from django.core.handlers.wsgi import WSGIRequest
from django.db import transaction
from rest_framework import status
from rest_framework.parsers import JSONParser

from juqiadmin.auth import login_auth, check_admin
from jqpage.pagination import JQPagination

from collections import Counter

from .models import (
    YifanshangGame,
    YifanshangSonGame,
    YifanshangGameGood,
    YifanshangRaffleRecord,
)

from .serializers import (
    YifanshangGameSerializer,
    YifanshangSonGameSerializer,
    YifanshangRaffleRecordSerializer,
    fill_yfs_raffle_record,
    YifanshangGameGoodSerializer,
    fill_yfs,
    fill_game_good,
    fill_xcx_game_list,
)

from quanjushang.ser import Percentage_calculation
from jqpackage.models import UserPackageGoods

from wxuser.models import (
    UserHunJingRecord,
    UserScoreRecord,
    UserStoredMoneyRecord,
    Users,
    UserPackage,
    UserPackageRecord,
    UserOrder,
    add_user_order_goods,
)

from wxcloudrun.views import order_uuid

from warehouse.models import JuqiGood, GoodLevel, GoodLevelGameType
from juqiadmin.models import Finance, get_game_finance, get_wxuser_finance
from jqgame.basegame import GameType

from jqexception.jqexecption import ValueErr, UnknowErr, RightErr, NullErr, OverlordErr

from traceback import format_exc

import logging

logger = logging.getLogger("log")

from .cache import CacheLock

cache = CacheLock()

overlord_method = 10


class TestApiView(View):
    def get(self, request, *args, **kwargs):
        return JsonResponse({})


class YfsGameView(View):
    # 获取池子列表
    @check_admin
    def get(self, request, *args, **kwargs):
        state = request.GET.get("state", None)
        game_uuid = request.GET.get("uuid", None)
        game_name = request.GET.get("name", None)

        filters = {"deleted": False}
        if game_uuid:
            filters["uuid"] = game_uuid
        if game_name:
            filters["name"] = game_name
        if state:
            filters["state"] = state

        objs = YifanshangGame.objects.filter(**filters).order_by("-id")
        if not objs:
            return JsonResponse(
                {"code": 0, "data": {}, "msg": ""}, status=status.HTTP_200_OK
            )

        paginator = JQPagination(YifanshangGameSerializer)
        _data = paginator.paginate(objs, request)

        return JsonResponse(
            data={"code": 0, "data": _data, "msg": ""}, status=status.HTTP_200_OK
        )

    # 新增池子同步创建箱子
    @check_admin
    @transaction.atomic
    def post(self, request, *args, **kwargs):
        body = JSONParser().parse(request)
        raffle_counts = body["raffle_counts"]

        if raffle_counts is None or len(raffle_counts) == 0:
            raise ValueErr

        game = YifanshangGameSerializer(data=body)
        if game.is_valid(raise_exception=True):
            game.save()
        game = YifanshangGame.objects.filter(uuid=game.data.get("uuid")).first()

        son_games = []
        for num in range(1, body["game_num"] + 1):
            son_game = {
                "game_uuid": game.uuid,
                "price": game.price,
                "box_num": num,
            }
            son_games.append(YifanshangSonGame(**son_game))
        YifanshangSonGame.objects.bulk_create(son_games)

        yfs_son_games = YifanshangSonGame.objects.filter(game_uuid=game.uuid)

        _data = {
            "code": 0,
            "data": {
                "game": YifanshangGameSerializer(game).data,
                "son_game": YifanshangSonGameSerializer(yfs_son_games, many=True).data,
            },
            "msg": "创建成功",
        }

        return JsonResponse(data=_data, status=status.HTTP_201_CREATED)

    # 修改池子信息
    @check_admin
    @transaction.atomic
    def put(self, request, *args, **kwargs):
        body = JSONParser().parse(request)

        YifanshangGame.objects.select_for_update()

        game_uuid = body.pop("game_uuid")
        yfs_game_obj = (
            YifanshangGame.objects.filter(deleted=False).filter(uuid=game_uuid).first()
        )
        if yfs_game_obj is None:
            raise NullErr

        yfs_game_s = YifanshangGameSerializer(
            instance=yfs_game_obj, data=body, partial=True
        )
        try:
            # 如果池子价格发生变更修改箱子价格
            if yfs_game_obj.price != body["price"]:
                _ = (
                    YifanshangSonGame.objects.select_for_update()
                    .filter(game_uuid=game_uuid)
                    .update(price=body["price"])
                )

            yfs_game_s.is_valid(raise_exception=True)
            yfs_game_s.save()

            return JsonResponse({"code": 0, "msg": "ok"}, status=status.HTTP_200_OK)
        except Exception:
            raise UnknowErr

    # 删除池子同步删除箱子
    @check_admin
    @transaction.atomic
    def delete(self, request, *args, **kwargs):
        body = JSONParser().parse(request)

        _ = (
            YifanshangGame.objects.select_for_update()
            .filter(uuid=body["game_uuid"])
            .update(deleted=True)
        )
        _ = (
            YifanshangSonGame.objects.select_for_update()
            .filter(game_uuid=body["game_uuid"])
            .update(deleted=True)
        )

        return JsonResponse({"code": 0, "msg": "删除成功"}, status=status.HTTP_200_OK)


class YfsGameStateView(View):
    @check_admin
    @transaction.atomic
    def put(self, request, *args, **kwargs):
        body = JSONParser().parse(request)

        game_uuid = body.get("game_uuid", None)
        state = body.get("state", 0)
        if game_uuid is None:
            raise ValueErr

        YifanshangGame.objects.filter(uuid=game_uuid).update(state=state)
        YifanshangSonGame.objects.filter(game_uuid=game_uuid).update(state=state)

        return JsonResponse(
            {"code": 0, "data": {}, "msg": ""}, status=status.HTTP_200_OK
        )


class YfsGameDetailView(View):
    @check_admin
    def get(self, request, *args, **kwargs):
        game_uuid = request.GET.get("uuid", None)
        if game_uuid is None:
            raise UnknowErr

        game = YifanshangGame.objects.get(uuid=game_uuid)
        if game is None:
            return ValueErr

        _data = YifanshangGameSerializer(game).data
        _data["price"] = _data["price"] / 100

        return JsonResponse(
            {"code": 0, "data": _data, "msg": ""}, status=status.HTTP_200_OK
        )


class YfsGoodDetailView(View):
    @check_admin
    def get(self, request, *args, **kwargs):
        game_good_uuid = request.GET.get("uuid", None)
        if game_good_uuid is None:
            raise ValueError

        game_good = (
            YifanshangGameGood.objects.filter(uuid=game_good_uuid)
            .filter(deleted=False)
            .first()
        )
        if game_good is None:
            raise NullErr

        state = "0"

        # 如果抽过奖不可修改
        yfs_record = YifanshangRaffleRecord.objects.filter(
            good_uuid=game_good.good_uuid
        ).first()
        if yfs_record:
            state = "1"

        _data = YifanshangGameGoodSerializer(game_good).data

        k_list = ["name", "price", "recovery_price", "display_url"]
        for k, v in _data["detail"].items():
            if k_list.count(k) > 0:
                # if k == "price" or k == "recovery_price":
                #     _data[k] = v / 100
                # else:
                _data[k] = v

        return JsonResponse(
            {"code": 0, "data": _data, "state": state, "msg": ""},
            status=status.HTTP_200_OK,
        )


class YfsGoodView(View):
    @check_admin
    def get(self, request, *args, **kwargs):
        game_uuid = request.GET.get("game_uuid", None)
        if game_uuid is None:
            raise ValueError

        son_game = YifanshangSonGame.objects.filter(
            game_uuid=game_uuid, deleted=False
        ).first()
        if son_game is None:
            raise NullErr

        game_goods = YifanshangGameGood.objects.filter(
            game_uuid=son_game.uuid, deleted=False
        ).order_by("id")

        paginator = JQPagination(YifanshangGameGoodSerializer)
        data = paginator.paginate(game_goods, request)

        _data = []
        for g in data.get("list", []):
            _data.append(fill_game_good(g))

        data["list"] = _data

        return JsonResponse(
            {"code": 0, "data": _data, "msg": ""}, status=status.HTTP_200_OK
        )

    # 商品绑定池子
    @check_admin
    @transaction.atomic
    def post(self, request, *args, **kwargs):
        body = JSONParser().parse(request)
        game_uuid = body.get("game_uuid")

        son_games = YifanshangSonGame.objects.filter(game_uuid=game_uuid)

        level = GoodLevel.objects.filter(uuid=body["good_level_uuid"]).first()
        if level is None:
            raise ValueError

        # 先创建到Goods
        jq_good = JuqiGood.objects.create(
            name=body["name"],
            display_url=body["display_url"],
            price=body["price"],
            recovery_price=body["recovery_price"],
            game_type="一番赏",
            level_title=level.title,
        )

        good_presale_type = body.get("good_presale_type", "现货")
        game_goods = []
        for son_game in son_games:
            game_good = {
                "game_uuid": son_game.uuid,
                "good_uuid": jq_good.uuid,
                "good_type": 1 if not level.method_type else 0,
                "good_level_uuid": body["good_level_uuid"],
                "good_presale_type": good_presale_type,
                "good_desc_url": body["img_desc_url"],
                "count": body["count"],
                "current_count": body["count"],
            }

            if good_presale_type == "预售":
                game_good["good_presale_time"] = datetime.datetime.strptime(
                    body["good_presale_time"], "%Y-%m-%d"
                )
            game_goods.append(YifanshangGameGood(**game_good))

            if level.method_type == 0:
                son_game.raffle_count += body["count"]
                son_game.remaining_raffle_count += body["count"]
            son_game.save()

        YifanshangGameGood.objects.bulk_create(game_goods)

        return JsonResponse(
            {"code": 0, "data": {"game_uuid": game_uuid}, "msg": "创建成功"},
            status=status.HTTP_201_CREATED,
        )

    @transaction.atomic
    def put(self, request, *args, **kwargs):
        body = JSONParser().parse(request)

        game_uuid = body.get("game_uuid", None)
        good_uuid = body.get("good_uuid", None)
        good_level_uuid = body.get("good_level_uuid", None)
        count = body.get("count")
        if (good_uuid or game_uuid or good_level_uuid) is None:
            raise UnknowErr

        son_games_uuid_list = YifanshangSonGame.objects.filter(
            game_uuid=game_uuid
        ).values_list("uuid", flat=True)

        game_goods = YifanshangGameGood.objects.filter(
            good_uuid=good_uuid, game_uuid__in=list(son_games_uuid_list)
        )
        if len(game_goods) < 1:
            raise UnknowErr

        old_level = GoodLevel.objects.filter(uuid=game_goods[0].good_level_uuid).first()
        new_level = GoodLevel.objects.filter(uuid=good_level_uuid).first()

        # 先修改juqi_good表
        jq_good = JuqiGood.objects.filter(uuid=good_uuid).select_for_update().first()
        if jq_good is None:
            raise ValueError
        jq_good.name = body.get("name")
        jq_good.display_url = body.get("display_url")
        jq_good.price = body.get("price")
        jq_good.recovery_price = body.get("recovery_price")
        jq_good.level_title = new_level.title
        jq_good.detail = body.get("desc")
        jq_good.save()

        # 修改yifanshang good表
        good_presale_type = body.get("good_presale_type", "现货")
        son_game_list = []
        game_goods_s = []
        for good in game_goods:
            son_game = YifanshangSonGame.objects.filter(uuid=good.game_uuid).first()
            if not old_level.method_type:
                son_game.raffle_count -= good.count
                son_game.remaining_raffle_count -= good.count
            if not new_level.method_type:
                son_game.raffle_count += count
                son_game.remaining_raffle_count += count

            good.good_type = 1 if not new_level.method_type else 0
            good.good_presale_type = good_presale_type
            good.good_level_uuid = body.get("good_level_uuid")
            good.good_desc_url = body.get("img_desc_url")
            good.count = count
            good.current_count = count
            if good_presale_type == "预售":
                good.good_presale_time = datetime.datetime.strptime(
                    body["good_presale_time"], "%Y-%m-%d"
                )
            son_game_list.append(son_game)
            game_goods_s.append(good)

        YifanshangSonGame.objects.bulk_update(
            son_game_list,
            fields=[
                "raffle_count",
                "remaining_raffle_count",
            ],
        )

        YifanshangGameGood.objects.bulk_update(
            game_goods_s,
            fields=[
                "good_type",
                "good_level_uuid",
                "good_presale_type",
                "good_desc_url",
                "count",
                "current_count",
            ],
        )

        return JsonResponse(
            {"code": 0, "data": {}, "msg": "修改成功"},
            status=status.HTTP_200_OK,
        )

    # 池子删除商品
    @check_admin
    @transaction.atomic
    def delete(self, request, *args, **kwargs):
        body = JSONParser().parse(request)

        game_uuid = body.get("game_uuid", None)
        good_uuid = body.get("good_uuid", None)
        if game_uuid is None or good_uuid is None:
            raise UnknowErr

        game = YifanshangGame.objects.get(uuid=game_uuid)
        if game is None:
            raise UnknowErr
        if game.state == 1:
            return JsonResponse(
                {"code": 0, "data": {}, "msg": "删除失败,池子已上线"}, status=status.HTTP_200_OK
            )

        yfs_son_game = YifanshangSonGame.objects.filter(game_uuid=game_uuid)
        if yfs_son_game is None or len(yfs_son_game) < 1:
            raise ValueError

        yfs_game_good = YifanshangGameGood.objects.filter(
            game_uuid=yfs_son_game[0].uuid
        ).first()
        if yfs_game_good is None:
            raise ValueError

        good_level = GoodLevel.objects.filter(
            uuid=yfs_game_good.good_level_uuid
        ).first()
        if good_level is None:
            raise ValueError

        del_yfs_game_good = []
        update_son_game = []

        goods = YifanshangGameGood.objects.filter(
            game_uuid__in=yfs_son_game.values_list("uuid"), good_uuid=good_uuid
        )
        for g in goods:
            g.deleted = True
            del_yfs_game_good.append(g)

        for son_game in yfs_son_game:
            if good_level.method_type == 0:
                son_game.raffle_count -= yfs_game_good.count
                son_game.remaining_raffle_count -= yfs_game_good.count
                update_son_game.append(son_game)

        YifanshangGameGood.objects.bulk_update(del_yfs_game_good, fields=["deleted"])

        if len(update_son_game) > 0:
            YifanshangSonGame.objects.bulk_update(
                update_son_game, fields=["raffle_count", "remaining_raffle_count"]
            )

        return JsonResponse(
            {"code": 0, "data": {}, "msg": ""}, status=status.HTTP_200_OK
        )


class YfsSonGameView(View):
    # 箱子列表
    @check_admin
    def get(self, request, *args, **kwargs):
        game_uuid = request.GET.get("game_uuid")

        objs = YifanshangSonGame.objects.filter(game_uuid=game_uuid).order_by("id")

        paginator = JQPagination(YifanshangSonGameSerializer)
        _data = paginator.paginate(objs, request)

        return JsonResponse(
            {"code": 0, "data": _data, "msg": ""}, status=status.HTTP_200_OK
        )


class YfsFinanceView(View):
    @check_admin
    def get(self, request, *args, **kwargs):
        game_uuid = request.GET.get("game_uuid")

        all_raffle_income, all_raffle_cost, all_raffle_profit = 0, 0, 0

        yfs = YifanshangGame.objects.filter(uuid=game_uuid).first()
        if yfs:
            yfs_son_games = YifanshangSonGame.objects.filter(game_uuid=game_uuid)
            son_game_uuids = []
            for g in yfs_son_games:
                son_game_uuids.append(g.uuid)
            finances = Finance.objects.filter(user_uuid__in=son_game_uuids)
            for f in finances:
                all_raffle_income += f.all_raffle_income
                all_raffle_cost += f.all_raffle_cost
                all_raffle_profit += f.all_raffle_profit
        else:
            f = Finance.objects.get(user_uuid=game_uuid)
            if f:
                all_raffle_income, all_raffle_cost, all_raffle_profit = (
                    f.all_raffle_income,
                    f.all_raffle_cost,
                    f.all_raffle_profit,
                )

        _data = {
            "code": 0,
            "data": {
                "all_raffle_income": all_raffle_income,
                "all_raffle_cost": all_raffle_cost,
                "all_raffle_profit": all_raffle_profit,
            },
            "msg": "",
        }
        return JsonResponse(data=_data, status=status.HTTP_200_OK)


# 小程序端接口
class XcxYfsGameView(View):
    @login_auth
    def get(self, request, *args, **kwargs):
        games = YifanshangGame.objects.filter(state=1, deleted=False).order_by("sort")
        if not games or len(games) == 0:
            return JsonResponse(
                {"code": 0, "data": {}, "msg": ""}, status=status.HTTP_200_OK
            )

        _data = fill_xcx_game_list(games)
        return JsonResponse(
            {"code": 0, "data": _data, "msg": ""}, status=status.HTTP_200_OK
        )


class XcxYfsSonGameDetail(View):
    @login_auth
    def get(self, request, *args, **kwargs):
        son_game_uuid = request.GET.get("game_uuid", "")

        son_game = (
            YifanshangSonGame.objects.filter(uuid=son_game_uuid)
            .filter(deleted=False)
            .filter(state=1)
            .first()
        )
        if son_game is None:
            return JsonResponse(
                {"code": 0, "data": {}, "msg": ""}, status=status.HTTP_200_OK
            )

        son_game_goods = (
            YifanshangGameGood.objects.filter(game_uuid=son_game_uuid)
            .filter(deleted=False)
            .order_by("id")
        )

        good_info = []
        for good in son_game_goods:
            level = GoodLevel.objects.get(uuid=good.good_level_uuid)
            good_info.append(f"{level.title}: {good.current_count}/{good.count}")

        return JsonResponse(
            data={
                "code": 0,
                "data": {
                    "game_uuid": son_game.uuid,
                    "box_num": son_game.box_num,
                    "good": good_info,
                    "remaining_raffle_count": son_game.remaining_raffle_count,
                },
                "msg": "",
            },
            status=status.HTTP_200_OK,
        )


class XcxYfsSonGameView(View):
    @login_auth
    def get(self, request, *args, **kwargs):
        game_uuid = request.GET.get("uuid")
        son_game_uuid = request.GET.get("game_uuid", "")

        yfs_game = YifanshangGame.objects.filter(uuid=game_uuid).first()
        if yfs_game is None:
            return ValueErr

        yfs_son_games = (
            YifanshangSonGame.objects.filter(game_uuid=game_uuid)
            .filter(deleted=False)
            .filter(state=1)
            .order_by("box_num")
        )

        if yfs_son_games is None or len(yfs_son_games) == 0:
            return JsonResponse(
                data={"code": 0, "data": {}, "msg": ""}, status=status.HTTP_200_OK
            )

        # 赋值当前son_game.object
        son_game_uuid_list = []
        up_box_uuid, down_box_uuid = "", ""
        current_son_game = None
        _status = False
        for s_g in yfs_son_games:
            if not _status:
                if str(s_g.uuid) == son_game_uuid:
                    current_son_game = s_g
                    _status = True
                son_game_uuid_list.append(str(s_g.uuid))

        if not _status:
            current_son_game = yfs_son_games[0]
            son_game_uuid = str(current_son_game.uuid)

        # 计算上一个、下一个箱子的uuid
        son_game_index = 0
        if son_game_uuid != "":
            try:
                son_game_index = son_game_uuid_list.index(son_game_uuid)
            except IndexError:
                son_game_index = 0
        if son_game_index == 0 and len(yfs_son_games) > 0:
            down_box_uuid = yfs_son_games[1].uuid
        elif len(yfs_son_games) == son_game_index + 1:
            up_box_uuid = yfs_son_games[son_game_index - 1].uuid
        else:
            up_box_uuid = yfs_son_games[son_game_index - 1].uuid
            down_box_uuid = yfs_son_games[son_game_index + 1].uuid

        # 统计当前箱子的商品
        game_good = YifanshangGameGood.objects.filter(
            game_uuid=son_game_uuid, deleted=False
        ).order_by("id")

        good_uuid_list = []
        good_level_uuid_list = []
        for good in game_good:
            good_uuid_list.append(good.good_uuid)
            good_level_uuid_list.append(good.good_level_uuid)

        jq_good_dict = {}
        jq_goods = JuqiGood.objects.filter(uuid__in=good_uuid_list).order_by()
        for jq_good in jq_goods:
            jq_good_dict[str(jq_good.uuid)] = jq_good

        good_level_dict = {}
        good_level_objs = GoodLevel.objects.filter(uuid__in=good_level_uuid_list)
        for good_level_obj in good_level_objs:
            good_level_dict[str(good_level_obj.uuid)] = good_level_obj

        good_dict = {}
        for good in game_good:
            level = good_level_dict.get(str(good.good_level_uuid))
            if not level.method_type:
                good_dict[good.good_uuid] = good.current_count

        probability_dict = Percentage_calculation(good_dict)

        good_info = []
        for good in game_good:
            jq_good = jq_good_dict[str(good.good_uuid)]
            level = good_level_dict.get(str(good.good_level_uuid))

            probability = ""
            if not level.method_type:
                if (
                    good.current_count > 0
                    and current_son_game.remaining_raffle_count > 0
                ):
                    probability = probability_dict.get(good.good_uuid, "")
                else:
                    probability = "0%"

            good_info.append(
                {
                    "name": jq_good.name,
                    "display_url": jq_good.display_url,
                    "good_desc_url": good.good_desc_url,
                    "good_level": level.title,
                    "good_level_url": level.img_url,
                    "price": current_son_game.price,
                    "count": good.count,
                    "current_count": good.current_count,
                    "probability": probability,
                }
            )

        in_overlord, overlord_second = False, 0
        if yfs_game.is_overlord:
            if cache.exit_lock(str(current_son_game.uuid)):
                in_overlord = True
                overlord_second = cache.ttl_lock(str(current_son_game.uuid))

        return JsonResponse(
            {
                "code": 0,
                "data": {
                    "raffle_counts": eval(yfs_game.raffle_counts),
                    "good": good_info,
                    "in_overlord": in_overlord,
                    "overlord_second": overlord_second,
                    "up_box_uuid": up_box_uuid,
                    "down_box_uuid": down_box_uuid,
                },
                "msg": "",
            },
            status=status.HTTP_200_OK,
        )


class XcxYfsSonGameListView(View):
    @login_auth
    def get(self, request, *args, **kwargs):
        game_uuid = request.GET.get("game_uuid")
        _expuuid = YifanshangGame.objects.filter(uuid=game_uuid).first()

        son_games = (
            YifanshangSonGame.objects.filter(game_uuid=game_uuid)
            .filter(deleted=False)
            .filter(state=1)
            .order_by("box_num")
        )

        paginator = JQPagination(YifanshangSonGameSerializer)
        _data = paginator.paginate(son_games, request)

        son_game_list = []
        son_games_uuids = []
        for g in _data.get("list", []):
            son_games_uuids.append(g.get("uuid"))
            son_game_list.append(
                {
                    "game_uuid": g.get("uuid"),
                    "box_num": g.get("box_num"),
                    "remaining_raffle_count": g.get("remaining_raffle_count"),
                }
            )

        for g in son_game_list:
            game_goods = YifanshangGameGood.objects.filter(
                game_uuid=g.get("game_uuid"), deleted=False
            ).order_by("id")

            good_info = []
            for good in game_goods:
                level = GoodLevel.objects.get(uuid=good.good_level_uuid)
                good_info.append(f"{level.title}: {good.current_count}/{good.count}")

            g["good"] = good_info

        _data["list"] = son_game_list

        return JsonResponse(
            data={"code": 0, "data": _data, "msg": "", "explain": _expuuid.explain},
            status=status.HTTP_200_OK,
        )

    # 一番赏抽奖
    @login_auth
    @transaction.atomic
    def post(self, request, *args, **kwargs):
        u = kwargs["user_info"]
        if u.type != "wxuser":
            raise RightErr

        openid = u.openid

        body = JSONParser().parse(request)

        stored_money = body.pop("stored_money", 0)
        hunjing = body.pop("hunjing", 0)
        score = body.pop("score", 0)

        game_uuid = body.pop("game_uuid")
        son_game_uuid = body.pop("son_game_uuid")
        raffle_count = body.pop("raffle_count")
        if stored_money == 1 and hunjing == 1 and score == 1:
            raise UnknowErr

        user = (
            Users.objects.filter(openid=openid)
            .filter(deleted=False)
            .select_for_update()
            .first()
        )
        if not user:
            raise NullErr

        game = (
            YifanshangGame.objects.filter(uuid=game_uuid)
            .filter(deleted=False)
            .select_for_update()
            .first()
        )
        if not game:
            raise NullErr
        if game.state != 1:
            raise UnknowErr

        son_game = (
            YifanshangSonGame.objects.filter(uuid=son_game_uuid)
            .filter(deleted=False)
            .select_for_update()
            .first()
        )
        if not son_game:
            raise NullErr

        # 先校验是否可以抽奖
        if son_game.remaining_raffle_count == 0:
            res = {"code": -1, "msg": "当前箱子已无剩余抽奖次数"}
            return JsonResponse(res, status=status.HTTP_200_OK, safe=False)

        # 是否开启霸主模式,开启霸主模式后查询redis.key
        if game.is_overlord:
            state = cache.exit_raffle(lock_key=son_game_uuid, user_uuid=str(user.uuid))
            if not state:
                return JsonResponse(
                    data={"code": 1, "data": {}, "msg": "当前箱子已锁定,请稍候"},
                    status=status.HTTP_200_OK,
                )

        # type=str: 全收
        if type(raffle_count) == str:
            # 校验是否可以全收,全收的抽奖次数=箱子剩余抽奖次数
            user_yfs_rr = YifanshangRaffleRecord.objects.filter(
                user_uuid=user.uuid, game_uuid=son_game_uuid
            )
            if len(user_yfs_rr) < overlord_method:
                return JsonResponse(
                    {"code": 1, "data": {}, "msg": "暂未激活全收功能"},
                    status=status.HTTP_200_OK,
                )
            else:
                raffle_count = son_game.remaining_raffle_count
        elif type(raffle_count) == int:
            # 如果用户抽奖次数大于剩余可抽奖次数，重新赋值
            if raffle_count > son_game.remaining_raffle_count:
                raffle_count = son_game.remaining_raffle_count

            if raffle_count == 0:
                res = {"code": -1, "msg": "当前箱子已无剩余抽奖次数"}
                return JsonResponse(res, status=status.HTTP_200_OK, safe=False)
        else:
            raise ValueError

        user_order = UserOrder(
            user_uuid=user.uuid,
            game_uuid=game.uuid,
            son_uuid=son_game.uuid,
            box_num=son_game.box_num,
            orderid=order_uuid(prefix="CS_"),
            game_name=game.name,
            price=game.price,
            num=raffle_count,
            game_type=GameType.yifanshang.value,
        )

        # 支付金额校验
        currency = get_user_pay_currency(stored_money, hunjing, score, user)
        sum_price = game.price * raffle_count
        dzf = game.price * raffle_count

        print(currency, dzf, user.__dict__, "11112")

        if currency < sum_price:
            res = {"code": -1, "msg": "余额不足"}
            transaction.set_rollback(True)  # 强制回滚
            return JsonResponse(res, status=status.HTTP_200_OK, safe=False)

        # 校验该箱子是否存在锁
        if game.is_overlord and cache.exit_lock(lock_key=son_game_uuid):
            if cache.check_lock_user(lock_key=son_game_uuid, user_uuid=str(user.uuid)):
                if raffle_count == overlord_method:
                    cache.expire_lock(
                        lock_key=son_game_uuid,
                        user_uuid=str(user.uuid),
                        expires=game.overlord_second,
                    )
            else:
                transaction.set_rollback(True)  # 强制回滚
                return JsonResponse(
                    data={"code": 1, "data": {}, "msg": "当前箱子已锁定,请稍候"},
                    status=status.HTTP_200_OK,
                )
        # 箱子上锁
        else:
            if game.is_overlord and raffle_count == overlord_method:
                cache.get_lock(son_game_uuid, str(user.uuid), game.overlord_second)

        yfs_game_good = YifanshangGameGood.objects.filter(
            game_uuid=son_game_uuid, deleted=False
        ).filter(good_type=1)

        _goods = get_good_current_count(yfs_game_good)

        # 奖品抽取
        raffle = raffle_good(_goods, raffle_count)

        if raffle_count == son_game.remaining_raffle_count:
            yfs_game_zzs_good = YifanshangGameGood.objects.get(
                game_uuid=son_game_uuid, good_type=0, deleted=False
            )
            raffle.append(yfs_game_zzs_good.good_uuid)

        # 记录抽奖记录
        raffle_s = []
        current_raffle_count = 1  # 初始化抽奖发数: 用于抽赏记录的发数
        current_rr = (
            YifanshangRaffleRecord.objects.filter(game_uuid=son_game_uuid)
            .order_by("-id")
            .first()
        )
        if current_rr is not None:
            current_raffle_count = current_rr.raffle_count + 1
        yfs_rr_raffle_count = current_raffle_count
        for r in raffle:
            raffle_record = {
                "user_uuid": user.uuid,
                "game_uuid": son_game_uuid,
                "good_uuid": r,
                "raffle_count": yfs_rr_raffle_count,
            }
            raffle_s.append(YifanshangRaffleRecord(**raffle_record))
            yfs_rr_raffle_count += 1
        YifanshangRaffleRecord.objects.bulk_create(raffle_s)

        # 用户消费记录
        write_user_record(
            stored_money, hunjing, score, dzf, raffle_count, user, game, user_order
        )

        # 奖品放入用户背包
        good_save_user_package(
            raffle,
            user,
            game,
            son_game,
            current_raffle_count,
            user_order.uuid,
        )

        all_raffle_cost = 0
        for r in raffle:
            jq_good = JuqiGood.objects.get(uuid=r)
            all_raffle_cost += jq_good.recovery_price

        # 获取一番赏管理员的成本记录
        yfs_finance = get_game_finance(GameType.yifanshang)

        # 减去奖品数量
        dncr_game_good_count(
            raffle, son_game_uuid, raffle_count, user.uuid, game.name, yfs_finance
        )

        # 更新管理员成本记录
        if score!=1:
            yfs_finance.all_raffle_income += sum_price
        yfs_finance.all_raffle_cost += all_raffle_cost
        yfs_finance.all_raffle_profit = (
            yfs_finance.all_raffle_income - yfs_finance.all_raffle_cost
        )
        yfs_finance.save()

        # 游戏成本记录

        game_finance = get_wxuser_finance(GameType.yifanshang, user.uuid, game.uuid)
        if score!=1:
            game_finance.all_raffle_income += sum_price
        game_finance.all_raffle_cost += all_raffle_cost
        all_raffle_profit = (
            game_finance.all_raffle_income - game_finance.all_raffle_cost
        )
        game_finance.all_raffle_profit = all_raffle_profit
        game_finance.save()
        add_user_order_goods(user_order.uuid, raffle)

        # 更新用户剩余额度+赏柜价值
        user.save()
        # 组装response.data
        _data = []
        for good_uuid, count in dict(Counter(raffle)).items():
            jq_good = JuqiGood.objects.get(uuid=good_uuid)
            good = YifanshangGameGood.objects.get(
                good_uuid=good_uuid, game_uuid=son_game_uuid, deleted=False
            )

            for v in range(count):
                _data.append(
                    {
                        "name": jq_good.name,
                        "display_url": jq_good.display_url,
                        "good_desc_url": good.good_desc_url,
                        "count": 1,
                    }
                )
        random.shuffle(_data)
        return JsonResponse(
            data={"code": 0, "data": _data, "msg": ""}, status=status.HTTP_201_CREATED
        )


# get_good_current_count 获取箱子下剩余商品的good_uuid_list(重复)
def get_good_current_count(yfs_game_good):
    _good_uuid_list = []
    for g in yfs_game_good:
        if g.current_count > 0:
            for _ in range(1, g.current_count + 1):
                _good_uuid_list.append(g.good_uuid)
    return _good_uuid_list


def raffle_good(good_uuid_list, raffle_count):
    return sample(good_uuid_list, raffle_count)


# good_save_user_package 商品记录到用户背包中
def good_save_user_package(
    good_uuid_list: list,
    user_obj,
    game_obj,
    son_game_obj,
    current_raffle_count,
    user_order_uuid,
):
    ups_create = []
    for good_uuid in good_uuid_list:
        good = JuqiGood.objects.filter(uuid=good_uuid).first()

        game_good_obj = (
            YifanshangGameGood.objects.filter(game_uuid=son_game_obj.uuid)
            .filter(good_uuid=good_uuid)
            .first()
        )
        good_level_obj = (
            GoodLevel.objects.filter(game_type=GoodLevelGameType.yifanshang.value)
            .filter(uuid=game_good_obj.good_level_uuid)
            .first()
        )

        info = {
            "user_uuid": user_obj.uuid,
            "good_uuid": good_uuid,
            "good_level_title": good_level_obj.title,
            "game_type": GameType.yifanshang.value,
            "game_uuid": game_obj.uuid,
            "game_son_uuid": son_game_obj.uuid,
            "game_box_num": son_game_obj.box_num,
            "order_num": current_raffle_count,
            "order_uuid": user_order_uuid,
        }

        user_obj.package_amount = user_obj.package_amount + good.recovery_price

        current_raffle_count += 1

        ups_create.append(UserPackageGoods(**info))
    UserPackageGoods.objects.bulk_create(ups_create, batch_size=1000)


def dncr_game_good_count(
    good_uuid_list: list,
    game_uuid: str,
    raffle_count: int,
    user_uuid,
    game_name: str,
    yfs_finance,
):
    good_dict = dict(Counter(good_uuid_list))

    yfs_game_good_update = []
    for good_uuid, count in good_dict.items():
        yfs_game_good = YifanshangGameGood.objects.get(
            good_uuid=good_uuid, game_uuid=game_uuid, deleted=False
        )

        yfs_game_good.current_count -= count
        yfs_game_good_update.append(yfs_game_good)

    YifanshangGameGood.objects.bulk_update(
        yfs_game_good_update, ["current_count"], batch_size=1000
    )

    yfs_son_game = YifanshangSonGame.objects.get(uuid=game_uuid)
    yfs_son_game.remaining_raffle_count -= raffle_count
    if yfs_son_game.remaining_raffle_count == 0:
        yfs_game_zzs_good = YifanshangGameGood.objects.get(
            game_uuid=game_uuid, good_type=0, deleted=False
        )

        jq_good = JuqiGood.objects.get(uuid=yfs_game_zzs_good.good_uuid)
        yfs_finance.all_raffle_cost += jq_good.recovery_price
        # good_save_user_package(
        #     [yfs_game_zzs_good.good_uuid], user_uuid, game_name, yfs_son_game.box_num
        # )
    yfs_son_game.save()


def get_user_pay_currency(stored_money, hunjing, score: int, user):
    currency = 0
    if stored_money == 1:
        currency += user.stored_money
    if hunjing == 1:
        currency += user.hunjing
    if score == 1:
        currency += user.score
    return currency


def write_user_record(
    stored_money, hunjing, score: int, dzf, raffle_count: int, user, game, user_order
):
    if stored_money == 1:
        # 如果余额小于支付金额 扣完余额
        if user.stored_money < dzf:
            user_order.money = user.stored_money
            _old = user.stored_money
            _new = _old - user.stored_money
            dzf = dzf - user.stored_money
            user.stored_money = _new

        else:
            user_order.money = dzf
            _old = user.stored_money
            _new = _old - dzf
            user.stored_money = _new
            dzf = 0

        zfje = user_order.money

        _record = {
            "user_uuid": user.uuid,
            "stored_money": -zfje,
            "old_stored_money": _old,
            "new_stored_money": _new,
            "detail": f"{game.name}抽奖{raffle_count}次",
        }
        UserStoredMoneyRecord.objects.create(**_record)

    if hunjing == 1 and dzf > 0:
        # 如果余额支付存在 并且dzf不等于0
        if stored_money == 1 and dzf != 0:
            # 如果待支付余额大于魂晶 报错
            if dzf > user.hunjing:
                raise UnknowErr
            # 如果小于魂晶执行
            else:
                user_order.hunjing = dzf
                _old = user.hunjing
                _new = _old - dzf
                dzf = dzf - user_order.hunjing
                user.hunjing = _new

        # 如果积分存在 并且积分的金额小于待支付的 扣除全部积分
        elif score == 1 and user.hunjing < dzf:
            user_order.hunjing = user.hunjing
            _old = user.hunjing
            _new = _old - user.hunjing
            dzf = dzf - user_order.hunjing
            user.hunjing = _new

        # 条件不满足直接扣除
        else:
            user_order.hunjing = game.price
            _old = user.hunjing
            _new = _old - dzf
            user.hunjing = _new
            dzf = 0

        zfje = user_order.hunjing
        _record = {
            "user_uuid": user.uuid,
            "hunjing": -zfje,
            "old_hunjing": _old,
            "new_hunjing": _new,
            "detail": f"{game.name}抽奖{raffle_count} 次",
        }
        UserHunJingRecord(**_record).save()

    if score == 1 and dzf > 0:
        if stored_money == 1 or hunjing == 1:
            raise UnknowErr

        user_order.score = dzf
        _old = user.score
        _new = _old - dzf
        user.score = _new
        dzf = 0

        zfje = user_order.score
        _record = {
            "user_uuid": user.uuid,
            "score": -zfje,
            "old_score": _old,
            "new_score": _new,
            "detail": f"{game.name} 抽奖 {raffle_count} 次",
        }
        UserScoreRecord(**_record).save()
    if dzf != 0:
        raise UnknowErr

    user_order.save()
    # if stored_money == 1:
    #     # 如果余额小于支付金额 扣完余额
    #     if user.stored_money < sum_price:
    #         user_order.money = user.stored_money
    #         _old = user.stored_money
    #         _new = _old - user.stored_money
    #         dzf = sum_price - user.stored_money
    #         user.stored_money = _new

    #     else:
    #         user_order.money = sum_price
    #         _old = user.stored_money
    #         _new = _old - sum_price
    #         user.stored_money = _new
    #         dzf = 0

    #     zfje = user_order.money

    #     _record = {
    #         "user_uuid": user.uuid,
    #         "stored_money": -zfje,
    #         "old_stored_money": _old,
    #         "new_stored_money": _new,
    #         "detail": f"消耗余额{zfje}:{game.name}抽奖{raffle_count}次",
    #     }
    #     UserStoredMoneyRecord.objects.create(**_record)

    # if hunjing == 1 and sum_price > 0:
    #     # 如果余额支付存在 并且dzf不等于0
    #     if stored_money == 1 and sum_price != 0:
    #         # 如果待支付余额大于魂晶 报错
    #         if sum_price > user.hunjing:
    #             raise UnknowErr
    #         # 如果小于魂晶执行
    #         else:
    #             user_order.hunjing = sum_price
    #             _old = user.hunjing
    #             _new = _old - sum_price
    #             sum_price = sum_price - user_order.hunjing
    #             user.hunjing = _new

    #     # 如果积分存在 并且积分的金额小于待支付的 扣除全部积分
    #     if score == 1 and user.hunjing < sum_price:
    #         user_order.hunjing = user.hunjing
    #         _old = user.hunjing
    #         _new = _old - user.hunjing
    #         sum_price = sum_price - user_order.hunjing
    #         user.hunjing = _new

    #     # 条件不满足直接扣除
    #     else:
    #         user_order.hunjing = game.price
    #         _old = user.hunjing
    #         _new = _old - sum_price
    #         user.hunjing = _new
    #         dzf = 0

    #     zfje = user_order.hunjing
    #     _record = {
    #         "user_uuid": user.uuid,
    #         "hunjing": -zfje,
    #         "old_hunjing": _old,
    #         "new_hunjing": _new,
    #         "detail": f"消耗魂晶{zfje}:{game.name}抽奖{raffle_count} 次",
    #     }
    #     UserHunJingRecord(**_record).save()

    # if score == 1 and sum_price > 0:
    #     if (stored_money == 1 and sum_price != 0) or (hunjing == 1 and sum_price != 0):
    #         if user.score < sum_price:
    #             raise UnknowErr

    #         user_order.score = sum_price
    #         _old = user.score
    #         _new = _old - sum_price
    #         sum_price = sum_price - user_order.score
    #         user.score = _new

    #     else:
    #         user_order.score = game.price
    #         _old = user.score
    #         _new = _old - sum_price
    #         user.score = _new
    #         dzf = 0

    #     zfje = user_order.score
    #     _record = {
    #         "user_uuid": user.uuid,
    #         "score": -zfje,
    #         "old_score": _old,
    #         "new_score": _new,
    #         "detail": f"消耗积分 {zfje}: {game.name} 抽奖 {raffle_count} 次",
    #     }
    #     UserScoreRecord(**_record).save()
    # if sum_price != 0:
    #     raise UnknowErr


class YfsRaffleRecordView(View):
    @login_auth
    def get(self, request, *args, **kwargs):
        uuid = request.GET.get("uuid", None)
        if uuid is None:
            raise ValueError

        all_raffle_record = YifanshangRaffleRecord.objects.filter(
            game_uuid=uuid, deleted=False
        ).order_by("createdAt")
        if all_raffle_record is None:
            return JsonResponse(
                {"code": 0, "data": [], "msg": ""},
                status=status.HTTP_200_OK,
            )

        all_raffle_record_s = YifanshangRaffleRecordSerializer(
            all_raffle_record, many=True
        ).data

        _data = fill_yfs_raffle_record(all_raffle_record_s)

        return JsonResponse(
            {"code": 0, "data": _data[::-1], "msg": ""},
            status=status.HTTP_200_OK,
        )
